package com.emath.objects;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import com.emath.shared.Globals;
import com.emath.shared.NetUtils;

public class Collection extends AsyncTask<String, Void, String> {
	private List<Card> cardList = new ArrayList<Card>();
	private String collection;
	private String cardID = null;
	private String quantity;
	private String playDeck;
	private int numOfCardsInDeck;
	private String userID;
	private String bornOn;
	private String uniqueID;
	private String objectState = "";

	public void addCard(Card cardObj) {
		this.cardList.add(cardObj);
	}
	public String getObjectState() {
		return objectState;
	}
	public void setObjectState(String objectState) {
		this.objectState = objectState;
	}
	public String getCardID() {
		return cardID;
	}
	public void setCardID(String cardID) {
		this.cardID = cardID;
	}
	public String getCollection() {
		return collection;
	}
	public void setCollection(String collection) {
		this.collection = collection;
	}
	public String getQuantity() {
		return quantity;
	}
	public void setQuantity(String quantity) {
		this.quantity = quantity;
	}
	public String getPlayDeck() {
		return playDeck;
	}
	public void setPlayDeck(String playDeck) {
		this.playDeck = playDeck;
	}
	public String getUserID() {
		return userID;
	}
	public void setUserID(String userID) {
		this.userID = userID;
	}
	public String getBornOn() {
		return bornOn;
	}
	public void setBornOn(String bornOn) {
		this.bornOn = bornOn;
	}
	public List<Card> getCardList() {
		return cardList;
	}
	public Card getCardbyID(String id) {
		for (int i = 0; i < cardList.size(); i++)
			if (cardList.get(i).getCardID().equals(id))
				return cardList.get(i);
		return cardList.get(0);
	}
	public Card getCardFromList(int i) {
		return this.cardList.get(i);
	}
	public void setCardList(List<Card> cardLst) {
		cardList = cardLst;
	}
	public int getNumOfCardsInDeck() {
		return numOfCardsInDeck;
	}
	public void setNumOfCardsInDeck(int numOfCardsInDeck) {
		this.numOfCardsInDeck = numOfCardsInDeck;
	}
	public String getUniqueID() {
		return uniqueID;
	}
	public void setUniqueID(String uniqueID) {
		this.uniqueID = uniqueID;
	}

	public void sqlAddCard() throws Exception {
		final String URL = "http://emath-project.appspot.com/emath/emathservicehttp?function=newcard&userID="
				+ this.userID + "&cardID=" + this.cardID;
		if (this.objectState.equals("working")) {
			return;
		} else {
			this.objectState = "working";
		}
		new Thread(new Runnable() {
			public void run() {
				try {
					Card cardObj = new Card();
					cardObj.setCardID(getCardID());
					cardObj.sqlGetCard();

					HttpClient httpclient = new DefaultHttpClient();
					// Prepare a request object
					HttpGet httpget = new HttpGet(URL);
					// Execute the request
					// HttpResponse response;
					// response =
					httpclient.execute(httpget);
					// Get hold of the response entity
					getCardList().add(cardObj);
					setObjectState("free");
				} catch (ClientProtocolException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void sqlGetLibrary() throws Exception {
		final String URL = "http://emath-project.appspot.com/emath/emathservicehttp?function=getlibrary";
		if (this.objectState.equals("working")) {
			return;
		} else {
			this.objectState = "working";
		}
		new Thread(new Runnable() {
			public void run() {
				try {
					List<Card> listObj = new ArrayList<Card>();
					HttpClient httpclient = new DefaultHttpClient();
					// Prepare a request object
					HttpGet httpget = new HttpGet(URL);
					// Execute the request
					HttpResponse response;
					response = httpclient.execute(httpget);
					// Get hold of the response entity
					HttpEntity entity = response.getEntity();
					// If the response does not enclose an entity, there is no
					// need
					// to worry about connection release
					if (entity != null) {
						// A Simple JSON Response Read
						InputStream instream = entity.getContent();
						String result = NetUtils
								.convertStreamToString(instream);
						// A Simple JSONObject Creation
						JSONObject collectionJson = new JSONObject(result);
						JSONArray jsonArray = collectionJson
								.getJSONArray("libraryCards");
						ArrayList<JSONObject> arrays = new ArrayList<JSONObject>();
						for (int i = 0; i < jsonArray.length(); i++) {
							JSONObject anotherJsonObj = jsonArray
									.getJSONObject(i);
							arrays.add(anotherJsonObj);
						}
						JSONObject[] jsons = new JSONObject[arrays.size()];
						arrays.toArray(jsons);

						for (int i = 0; i < arrays.size(); i++) {
							Card cardObj = new Card();
							cardObj.setCardID(arrays.get(i).get("cardID")
									.toString());
							cardObj.setCardName(arrays.get(i)
									.getString("cardName").toString());
							cardObj.setType(arrays.get(i).getString("type")
									.toString());
							cardObj.setMind1(arrays.get(i).getString("mind1")
									.toString());
							cardObj.setMind2(arrays.get(i).getString("mind2")
									.toString());
							cardObj.setMind3(arrays.get(i).getString("mind3")
									.toString());
							cardObj.setCharm1(arrays.get(i).getString("charm1")
									.toString());
							cardObj.setCharm2(arrays.get(i).getString("charm2")
									.toString());
							cardObj.setCharm3(arrays.get(i).getString("charm3")
									.toString());
							cardObj.setStrength1(arrays.get(i)
									.getString("strength1").toString());
							cardObj.setStrength2(arrays.get(i)
									.getString("strength2").toString());
							cardObj.setStrength3(arrays.get(i)
									.getString("strength3").toString());
							cardObj.setCost(arrays.get(i).getString("cost")
									.toString());
							cardObj.setSpecial(arrays.get(i)
									.getString("special").toString());
							cardObj.setSpecialEffect(arrays.get(i)
									.getString("specialEffect").toString());
							cardObj.setCreatorID(arrays.get(i)
									.getString("creatorID").toString());
							cardObj.setSetName(arrays.get(i)
									.getString("setName").toString());
							cardObj.setLevelUp(arrays.get(i)
									.getString("levelUp").toString());
							cardObj.setImage(arrays.get(i).getString("image")
									.toString());
							cardObj.setMovie(arrays.get(i).getString("movie")
									.toString());
							cardObj.setWiki(arrays.get(i).getString("wiki")
									.toString());
							cardObj.setMusic(arrays.get(i).getString("music")
									.toString());
							// while (Globals.numOfBitmapsProcessing > 5) {}
							cardObj.setBitmapAfterImageSet();
							// wait here until the bitmap has downloaded
							while (cardObj.bitmap == null) {
							}
							listObj.add(cardObj);
						}// end of cardList creation loop

						Globals.libraryObj.setCardList(listObj);

						setObjectState("free");
						instream.close();
						httpclient.getConnectionManager().shutdown();
					}
				} catch (ClientProtocolException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void sqlGetCollection() throws Exception {
		final String URL = "http://emath-project.appspot.com/emath/emathservicehttp?function=getcollection&userID="
				+ this.userID;
		if (this.objectState.equals("working")) {
			return;
		} else {
			this.objectState = "working";
		}
		new Thread(new Runnable() {
			public void run() {
				try {
					List<Card> listObj = new ArrayList<Card>();
					HttpClient httpclient = new DefaultHttpClient();
					// Prepare a request object
					HttpGet httpget = new HttpGet(URL);
					// Execute the request
					HttpResponse response;
					response = httpclient.execute(httpget);
					// Get hold of the response entity
					HttpEntity entity = response.getEntity();
					// If the response does not enclose an entity, there is no
					// need
					// to worry about connection release
					if (entity != null) {
						// A Simple JSON Response Read
						InputStream instream = entity.getContent();
						String result = NetUtils
								.convertStreamToString(instream);
						// A Simple JSONObject Creation
						JSONObject collectionJson = new JSONObject(result);
						JSONArray jsonArray = collectionJson
								.getJSONArray("collectionCards");
						ArrayList<JSONObject> arrays = new ArrayList<JSONObject>();
						for (int i = 0; i < jsonArray.length(); i++) {
							JSONObject anotherJsonObj = jsonArray
									.getJSONObject(i);
							arrays.add(anotherJsonObj);
						}
						JSONObject[] jsons = new JSONObject[arrays.size()];
						arrays.toArray(jsons);
						// int librarySize = Globals.libraryObj.getCardList()
						// .size();
						for (int i = 0; i < arrays.size(); i++) {
							Card cardObj = new Card();
							cardObj.setCardID(arrays.get(i).get("cardID")
									.toString());
							cardObj.setCardName(arrays.get(i)
									.getString("cardName").toString());
							cardObj.setType(arrays.get(i).getString("type")
									.toString());
							cardObj.setMind1(arrays.get(i).getString("mind1")
									.toString());
							cardObj.setMind2(arrays.get(i).getString("mind2")
									.toString());
							cardObj.setMind3(arrays.get(i).getString("mind3")
									.toString());
							cardObj.setCharm1(arrays.get(i).getString("charm1")
									.toString());
							cardObj.setCharm2(arrays.get(i).getString("charm2")
									.toString());
							cardObj.setCharm3(arrays.get(i).getString("charm3")
									.toString());
							cardObj.setStrength1(arrays.get(i)
									.getString("strength1").toString());
							cardObj.setStrength2(arrays.get(i)
									.getString("strength2").toString());
							cardObj.setStrength3(arrays.get(i)
									.getString("strength3").toString());
							cardObj.setCost(arrays.get(i).getString("cost")
									.toString());
							cardObj.setSpecial(arrays.get(i)
									.getString("special").toString());
							cardObj.setSpecialEffect(arrays.get(i)
									.getString("specialEffect").toString());
							cardObj.setCreatorID(arrays.get(i)
									.getString("creatorID").toString());
							cardObj.setSetName(arrays.get(i)
									.getString("setName").toString());
							cardObj.setLevelUp(arrays.get(i)
									.getString("levelUp").toString());
							cardObj.setImage(arrays.get(i).getString("image")
									.toString());
							cardObj.setMovie(arrays.get(i).getString("movie")
									.toString());
							cardObj.setWiki(arrays.get(i).getString("wiki")
									.toString());
							cardObj.setMusic(arrays.get(i).getString("music")
									.toString());
							// reuse image from library list if available
							if (Globals.libraryObj.getObjectState().equals(
									"free"))
								cardObj.setBitmap(Globals.libraryObj
										.getCardList()
										.get(Integer.parseInt(cardObj
												.getCardID()) < 3 ? Integer
												.parseInt(cardObj.getCardID()) - 1
												: Integer.parseInt(cardObj
														.getCardID()) - 2)
										.getBitmap());
							else
								cardObj.setBitmapAfterImageSet();
							// don't proceed through this thread until the
							// cardObj
							// has finished setting the bitmap
							while (cardObj.bitmap == null) {
							}
							// finish building collection cardObj
							cardObj.setBornOn(arrays.get(i).getString("bornOn"));
							cardObj.setUniqueID(arrays.get(i).getString(
									"cardID")
									+ arrays.get(i).getString("bornOn"));
							cardObj.setPlayDeck(arrays.get(i)
									.getString("playDeck").equals("true") ? true
									: false);
							listObj.add(cardObj);
						}
						setCardList(listObj);
						instream.close();
						httpclient.getConnectionManager().shutdown();
					}
				} catch (ClientProtocolException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					setObjectState("free");
				}
			}
		}).start();
	}

	public void sqlGetPlayDeck() throws Exception {
		final String URL = "http://emath-project.appspot.com/emath/emathservicehttp?function=getplaydeck&userID="
				+ this.userID;
		new Thread(new Runnable() {
			public void run() {
				try {
					setObjectState("working");
					List<Card> listObj = new ArrayList<Card>();
					HttpClient httpclient = new DefaultHttpClient();
					// Prepare a request object
					HttpGet httpget = new HttpGet(URL);
					// Execute the request
					HttpResponse response;
					response = httpclient.execute(httpget);
					// Get hold of the response entity
					HttpEntity entity = response.getEntity();
					// If the response does not enclose an entity, there is no
					// need
					// to worry about connection release
					if (entity != null) {
						// A Simple JSON Response Read
						InputStream instream = entity.getContent();
						String result = NetUtils
								.convertStreamToString(instream);
						// A Simple JSONObject Creation
						JSONObject json = new JSONObject(result);
						setCollection(json.getString("collection"));
						String cardID = "", timeStamp = "", playDeck = "", section = "cardID";

						for (int i = 0; i < getCollection().length(); i++) {

							if (!(getCollection().substring(i, i + 1).equals(
									"|") || getCollection().substring(i, i + 1)
									.equals(","))) {
								if (section.equals("cardID"))
									cardID += getCollection().substring(i,
											i + 1);
								if (section.equals("timeStamp"))
									timeStamp += getCollection().substring(i,
											i + 1);
								if (section.equals("playDeck"))
									playDeck += getCollection().substring(i,
											i + 1);
							} else {
								if (section.equals("cardID"))
									section = "timeStamp";
								else if (section.equals("timeStamp"))
									section = "playDeck";
								else if (section.equals("playDeck")) {
									Card cardObj = new Card();
									section = "cardID";
									cardObj.setCardID(cardID);
									cardObj.setPlayDeck(playDeck
											.equals("false") ? false : true);
									cardObj.setBornOn(timeStamp);
									cardObj.sqlGetCard();
									while (!cardObj.getObjectState().equals(
											"free")) {
										// Thread.sleep(50);
									}
									listObj.add(cardObj);
									setCardList(listObj);
									cardID = "";
									timeStamp = "";
									playDeck = "";
								}

							}
						}
						// Closing the input stream will trigger connection
						// release
						setObjectState("free");
						instream.close();
						httpclient.getConnectionManager().shutdown();
					}
				} catch (ClientProtocolException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();

	}

	protected String doInBackground(String... urls) {
		String output = null;
		for (String url : urls) {
			output = getOutputFromUrl(url);
		}
		return output;
	}

	private String getOutputFromUrl(String url) {
		String output = null;
		try {
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(url);

			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity httpEntity = httpResponse.getEntity();
			output = EntityUtils.toString(httpEntity);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return output;
	}

}
